#include "filtroVentana.h"

FiltroVentana::FiltroVentana(QWidget *parent)
	: QMainWindow(parent), model(3,1), model2(1,3)
{
	ui.setupUi(this);
	setSeparable(true);

	ui.tabla1->setModel(&model);
	ui.tabla1->setItemDelegate(&delegate);
	ui.tabla2->setModel(&model2);
	ui.tabla2->setItemDelegate(&delegate);

	ui.tree->setModel(&fileModel);
	raiz = fileModel.index(QDir::currentPath() + "/filtros");
	ui.tree->setRootIndex(raiz);
	connect(ui.tree, SIGNAL(clicked(QModelIndex)), this, SLOT(fileClick(QModelIndex)));
}

FiltroVentana::~FiltroVentana(){

}

void FiltroVentana::setSeparable(bool sep){
	separable = sep;

	ui.tabla2->setVisible(separable);
	ui.spinFactorC->setVisible(separable);
	ui.labelFactorC->setVisible(separable);

	if(separable){
		ui.labelFactorF->setText("Factor fila");
	}else{
		ui.labelFactorF->setText("Factor");
	}
}

void FiltroVentana::changeSize(int row, int col){
	ui.filas->setValue(row);
	ui.columnas->setValue(col);

	if(separable){
		model.setRowCount(row);
		model.setColumnCount(1);
		model2.setRowCount(1);
		model2.setColumnCount(col);
	}else{
		model.setRowCount(row);
		model.setColumnCount(col);
	}
}

void FiltroVentana::changeRowSize(int row){
	model.setRowCount(row);
}

void FiltroVentana::changeColSize(int col){
	if(separable){
		model2.setColumnCount(col);
	}else{
		model.setColumnCount(col);
	}
}

bool FiltroVentana::checkFiltro(){
	int col = model.columnCount();
	int row = model.rowCount();
	double total = 0;
	for(int i = 0; i < row; i++){
		for(int j= 0; j < col; j++){
			QModelIndex index = model.index(i, j, QModelIndex());
			total += model.data(index).toInt();
		}
	}

	total /= double(ui.spinFactorF->value());

	if(total != 1){
		QErrorMessage error(this);
		error.showMessage(QString::fromUtf8("El kernel debería sumar 1"));
		error.exec();
		return false;
	}

	return true;
}

void FiltroVentana::writeModel(QDataStream &out, QStandardItemModel& model){
	for(int i = 0; i < model.rowCount(); i++){
		for(int j= 0; j < model.columnCount(); j++){
			QModelIndex index = model.index(i, j, QModelIndex());
			out << model.data(index).toInt();
		}
	}
}

void FiltroVentana::save(){
	//Comprueba si es un filtro válido ¿Hay que hacer esta comprobación??
	//if(checkFiltro()){
	QString filename = QDir::currentPath() + "/filtros";
	QString destino = QFileDialog::getSaveFileName(this,
								     tr("Guardar kernel"), filename , tr("Kernel Files (*.krn)"));
	if(!destino.isNull()){
		QFile file(destino);
		file.open(QIODevice::WriteOnly);
		QDataStream out(&file);


		int col = ui.columnas->value();
		int row = ui.filas->value();

		double factorf = ui.spinFactorF->value();
		double factorc = ui.spinFactorC->value();

		out << separable << row << col << factorf << factorc;
		writeModel(out, model);
		if(separable){
			writeModel(out, model2);
		}
		file.close();
		fileModel.refresh(raiz);
	}
	//}
}


void FiltroVentana::read(){
	QString fileName = QFileDialog::getOpenFileName(this, tr("Abrir kernel"),
									QDir::currentPath()+"/filtros");
	if(!fileName.isEmpty()){
		read(fileName);
	}
}

void FiltroVentana::readModel(QDataStream & in, QStandardItemModel& m, int row, int col){
	for(int i = 0; i < row; i++){
		for(int j= 0; j < col; j++){
			QModelIndex index = m.index(i, j, QModelIndex());
			int valor;
			in >> valor;
			m.setData(index, QVariant(valor));
		}
	}
}

void FiltroVentana::read(const QString & fileName){
	QFile file(fileName);
	file.open(QIODevice::ReadOnly);
	QDataStream in(&file);
	int row, col;
	double factorf, factorc;
	bool separable;
	in >> separable >> row >> col >> factorf >> factorc;

	setSeparable(separable);
	changeSize(row, col);
	ui.spinFactorF->setValue(factorf);
	ui.spinFactorC->setValue(factorc);

	if(separable){
		readModel(in, model, row, 1);
		readModel(in, model2, 1, col);
	}else{
		readModel(in, model, row, col);
	}
	file.close();
}

void FiltroVentana::fileClick(const QModelIndex & index){
	if(!fileModel.isDir(index)){
		read(fileModel.filePath(index));
	}
}

void FiltroVentana::getKernelSize(int& f, int& c) {
	f = model.rowCount();
	if(separable){	
		c = model2.columnCount();
	}else{

		c = model.columnCount();
	}
}

bool FiltroVentana::isSeparable() {
	return separable;
}

void FiltroVentana::getKernel(double *kernel) {
	int row = model.rowCount();
	int col = model.columnCount();
	int indice = 0;

	for(int i = 0; i < row; i++){
		for(int j = 0; j < col; j++){
			QModelIndex index = model.index(i, j, QModelIndex());
			kernel[indice++] = model.data(index).toInt() / double(ui.spinFactorF->value());
		}
	}


	if(separable){
		row = model2.rowCount();
		col = model2.columnCount();
		for(int i = 0; i < row; i++){
			for(int j = 0; j < col; j++){
				QModelIndex index = model2.index(i, j, QModelIndex());
				kernel[indice++] = model2.data(index).toInt() / ui.spinFactorC->value();
			}
		}
	}
}

void FiltroVentana::slotAplicar(){
	emit signalAplicar();
}

void FiltroVentana::nuevo(){
	if(filtroVentana.exec()){
		filtroVentana.actualizar(model, model2);
		setSeparable(filtroVentana.isSeparable());
		ui.spinFactorF->setValue(filtroVentana.getFactorF());
		ui.spinFactorC->setValue(filtroVentana.getFactorC());
		ui.filas->setValue(filtroVentana.getRow());
		ui.columnas->setValue(filtroVentana.getCol());
	}
}
